package azalea.mqtt.message.builder;

import azalea.mqtt.message.builder.impl.ConnectionDataImpl;
import azalea.mqtt.message.utils.ByteUtils;
import azalea.mqtt.message.utils.MqttStrUtils;

public class ConnectionMsgBuilder {
	public static byte[] connectV3_1(boolean usernameFlag,boolean passwordFlag,boolean willRetain,int willQoS,boolean willFlag,boolean cleanSession,int keeplive,String clientId,String willTopic,String willMessage,String userName,String password) {
		/**
|Bit        |7                |6              |5              |4  |3       |2          |1              |0
|           |User Name Flag   |Password Flag  |Will Retain    |Will QoS    |Will Flag  |Clean Session  |Reserved
|byte 8     |X                |X              |X              |X  |X       |X          |X              |0
		 */
		int flag=0x0;
		if(usernameFlag) {
			flag=flag|0b10000000;
		}
		if(passwordFlag) {
			flag=flag|0b01000000;
		}
		if(cleanSession) {
			flag=flag|0b00000010;
		}
		if(willFlag) {
			flag=flag|0b00000100;
		}
		willQoS=willQoS&0b00000011;
		flag=flag|(willQoS<<3);
		if(willRetain) {
			flag=flag|0b00100000;
		}
		//String clientId,String willTopic,String willMessage,String userName,String password
		
		/**
		 Figure 1.1 Structure of UTF-8 encoded strings

|bit     |7       |6       |5       |4       |3       |2       |1       |0
|byte 1  |string length MSB
|byte 2  |string length LSB
|byte 3  |UTF-8 Encoded CharacterData, if length > 0.
		 */
		byte[] buff=new byte[65535*3+7];
		byte[] clientIdBytes=MqttStrUtils.getUTF8Bytes(clientId);
		buff[0]=(byte)(clientIdBytes.length/256);
		buff[1]=(byte)(clientIdBytes.length%256);
		int len=2;
		ByteUtils.copy(clientIdBytes, buff, 0, len, clientIdBytes.length);
		len+=clientIdBytes.length;
		if(willTopic!=null) {
			byte[] willTopicBytes=MqttStrUtils.getUTF8Bytes(willTopic);
			byte[] lenbyte= {(byte)((willTopicBytes.length)>>8&0xff),(byte)(willTopicBytes.length&0xff)};
			ByteUtils.copy(lenbyte, buff, 0, len, 2);
			len+=2;
			ByteUtils.copy(willTopicBytes, buff, 0, len, willTopicBytes.length);
			len+=willTopicBytes.length;
		}
		if(usernameFlag) {
			byte[] userNameBytes=MqttStrUtils.getUTF8Bytes(userName);
			byte[] lenbyte= {(byte)((userNameBytes.length)>>8&0xff),(byte)(userNameBytes.length&0xff)};
			ByteUtils.copy(lenbyte, buff, 0, len, 2);
			len+=2;
			ByteUtils.copy(userNameBytes, buff, 0, len, userNameBytes.length);
			len+=userNameBytes.length;
		}
		if(passwordFlag) {
			byte[] passwordBytes=MqttStrUtils.getUTF8Bytes(password);
			byte[] lenbyte= {(byte)((passwordBytes.length)>>8&0xff),(byte)(passwordBytes.length&0xff)};
			ByteUtils.copy(lenbyte, buff, 0, len, 2);
			len+=2;
			ByteUtils.copy(passwordBytes, buff, 0, len, passwordBytes.length);
			len+=passwordBytes.length;
		}
		return ConnectionDataImpl.connect((byte)0x04, (byte)flag, keeplive, buff, len);
	}
	public static byte[] connack(boolean sessionPresent,ConnectionReturnCode responseCode) {
		byte[] response= {0,1,2,3,4,5};
		return ConnectionDataImpl.connack(sessionPresent,response[responseCode.getValue()]);
	}
	public static byte[] disconnect() {
		return ConnectionDataImpl.disconnect();
	}
	
}
